
#include "app_includes.h"

multimeter_t multimeter;

#define CS1237_BUFF_SIZE    (6)
__IO int32_t cs1237_buff[2][CS1237_BUFF_SIZE];
__IO uint16_t cs1237_buff_index = 0;

/*
 * 读取一次cs1237数据，读取到CS1237_BUFF_SIZE次后切换缓冲区并且返回标识
 */
uint8_t multimeter_read_data(void)
{
    static uint8_t cnt = 0;
    cs1237_buff[cs1237_buff_index][cnt++] = cs1237_read_adc(&board.adc_dev);
    if(cnt>=CS1237_BUFF_SIZE) {
        cnt = 0;
        cs1237_buff_index ^= 1;
        return 1;
    }
    return 0;
}


/* 求平均 */
static int32_t read_adc_average(void)
{
    __IO int32_t *adc_buff;
    static int32_t adc_average =0;
    static uint8_t adc_buff_cnt = 0;
    uint16_t i;
    int32_t max, min, total = 0;
    adc_buff = cs1237_buff[!cs1237_buff_index];
    max = min = adc_buff[0];
    for(i=0;i!=CS1237_BUFF_SIZE;i++) {
        total += adc_buff[i];
        if(adc_buff[i]>max)
            max = adc_buff[i];
        if(adc_buff[i]<min)
            min = adc_buff[i];
    }
    adc_average = (total - max - min )/(CS1237_BUFF_SIZE-2);
    return adc_average;
}

static uint8_t check_upper_limit(multimeter_t *m)
{
    uint32_t adc_value_abs = abs(m->adc_value);
    m->upper_limit = adc_value_abs>m->para[m->id].limit_max;
    return m->upper_limit;
}

static uint8_t check_lower_limit(multimeter_t *m)
{
    uint32_t adc_value_abs = abs(m->adc_value);
    m->lower_limit = adc_value_abs<m->para[m->id].limit_min;
    return m->lower_limit;
}

/* 两段以上系数计算 */
float section_map_cal(int32_t adc_value, multimeter_factor_t *section)
{
    uint8_t i;
    float result = 0;
    factor_int32_t *factor = section->section;
    uint8_t num = section->num;
    if(adc_value<=factor[0].adc)
        i = 0;
    else if(adc_value>=factor[num-1].adc)
        i = num-2;
    else {
        for(i=0;i!=num-1;i++) {
            if(adc_value>factor[i].adc && adc_value<factor[i+1].adc)
                break;
        }
    }    
    return factor[i].value + (adc_value-factor[i].adc)*(factor[i+1].value-factor[i].value)/(factor[i+1].adc-factor[i].adc);
}

int32_t map_cal(int32_t adc_value)
{
    uint16_t amp[]= {0,10,100,1000,10000};
    float result = 0;
    if(multimeter.para[multimeter.id].factor_type==kMeterFactorType_Section)
        result = section_map_cal(adc_value, (multimeter_factor_t *)multimeter.para[multimeter.id].factor);
    else 
        result = adc_value*storedata.r_ref[multimeter.gear]/(storedata.r_vref-adc_value); 
    return result*amp[multimeter.para[multimeter.id].point] - multimeter.para[multimeter.id].offset;
}

static void meter_cal(multimeter_t *m)
{
    float r_v;
    if(multimeter.change>0) {
        multimeter.change--;
        return;
    }
    check_upper_limit(&multimeter); //检查是否超上限
    if(multimeter.gear_auto) { //自动换挡
        if(multimeter.upper_limit && multimeter.gear<multimeter.gear_max) { //超过上限并且还有挡位可换
            multimeter.gear++;
            multimeter_select_gear(multimeter.gear);
            return;
        }
        else if(check_lower_limit(&multimeter) && multimeter.gear>0) {
            multimeter.gear--;
            multimeter_select_gear(multimeter.gear);
            return;
        }
    }
    //multimeter.value = multimeter.adc_value;
    
    if(multimeter.channel==kBoardMetetCh_R) {
        r_v = section_map_cal(multimeter.adc_value, (multimeter_factor_t *)multimeter.para[multimeter.id].factor)*1000;//计算电压 
        multimeter.value = map_cal(r_v);
        if(multimeter.r_mode==kMeter_Mode_B) {
            buzzer_sound(&board.buzzer, multimeter.value<500);
        }
    }
    else { //电压电流二极管挡位，计算出对应值
        multimeter.value = map_cal(multimeter.adc_value);
    }
    
}

void multimeter_select_channel(uint8_t channel)
{
    if(multimeter.channel!=channel) {
        multimeter.change = METER_CHANGE_NUM;
        multimeter.channel = channel;
        board_meter_select_ch(multimeter.channel);
        multimeter.gear_auto = 1; //默认自动挡位
        multimeter_select_gear(0);
    }
}

void multimeter_select_next_mode(void)
{
    if(multimeter.channel==kBoardMetetCh_R || multimeter.channel==kBoardMetetCh_D) {
        multimeter.r_mode++;
        multimeter.gear_auto = 0;
        if(multimeter.r_mode>=3) {
            multimeter.r_mode = 0;
            multimeter.gear_auto = 1; //选择R通道，默认auto
        }
        //能进入mode选择，说明已经是R通道了，只需要设置multimeter.channel即可
        if(multimeter.r_mode==kMeter_Mode_D) //选到了二极管档，切换到D通道
            multimeter.channel = kBoardMetetCh_D;
        else //切回到R通道
            multimeter.channel = kBoardMetetCh_R;
        multimeter_select_gear(0);
    }
}

static uint8_t ch_id_base[] = { METER_CH_V_BASE, METER_CH_MV_BASE, METER_CH_A_BASE, METER_CH_D_BASE, METER_CH_R_BASE};
static uint8_t ch_gear_num[] = {2, 2, 1, 1, 3};
/* 选择挡位 */
void multimeter_select_gear(uint8_t gear)
{
    multimeter.change = METER_CHANGE_NUM;
    multimeter.gear = gear;
    if(multimeter.channel==kBoardMetetCh_R) {
        board_r_select_ch(multimeter.gear);
    }
    else if(multimeter.channel==kBoardMetetCh_D) {
        board_r_select_ch(kBoardRCh_1);
    }
    else if(multimeter.channel==kBoardMetetCh_A) {
        board_ua_select_amp(kBoardMeterAmp_1);
    }
    else {
        board_ua_select_amp(gear);
    }
    multimeter.gear_max = ch_gear_num[multimeter.channel] - 1;
    multimeter.id = ch_id_base[multimeter.channel] + multimeter.gear;
    multimeter.update = 1;
}

static char *unit_name[] = {"V","mV","mA","A", "Ω", "kΩ","MΩ",};
#define SECTION_FACTOR_NUM  9
static multimeter_factor_t section_factor[SECTION_FACTOR_NUM] = {
    {&storedata.factor[0], 3},
    {&storedata.factor[3], 3},
    {&storedata.factor[6], 3},
    {&storedata.factor[9], 3},
    {&storedata.factor[12], 3},
    {&storedata.factor[15], 2}, //D
    {&storedata.factor[15], 2}, //R1
    {&storedata.factor[17], 2},
    {&storedata.factor[19], 2},
};

void multimeter_init(void)
{
    uint16_t i;
    //初始化单位
    multimeter.unit_name = unit_name;
    multimeter.para[kMeterCh_V_10Amp].unit = 0;
    multimeter.para[kMeterCh_V_1Amp].unit = 0;
    multimeter.para[kMeterCh_mV_10Amp].unit = 1;
    multimeter.para[kMeterCh_mV_1Amp].unit = 1;
    multimeter.para[kMeterCh_A_1Amp].unit = 3;
    multimeter.para[kMeterCh_D].unit = 0;
    multimeter.para[kMeterCh_R].unit = 4;
    multimeter.para[kMeterCh_R_K].unit = 5;
    multimeter.para[kMeterCh_R_M].unit = 6;
    //初始化小数点
    multimeter.para[kMeterCh_V_10Amp].point = 3; //19.999V
    multimeter.para[kMeterCh_V_1Amp].point = 2; //199.99V
    multimeter.para[kMeterCh_mV_10Amp].point = 2; //199.99mV
    multimeter.para[kMeterCh_mV_1Amp].point = 1; //1999.9mV
    //multimeter.para[4].point = 1; //999.9mA
    multimeter.para[kMeterCh_A_1Amp].point = 3; //9.999A
    multimeter.para[kMeterCh_D].point = 3; //0.999V
    multimeter.para[kMeterCh_R].point = 1; //1999.9R
    multimeter.para[kMeterCh_R_K].point = 2; //199.99K
    multimeter.para[kMeterCh_R_M].point = 3; //19.999M   
    //初始化上下限
    multimeter.para[kMeterCh_V_10Amp].limit_max = 0.85*METER_ADC_MAX;
    multimeter.para[kMeterCh_V_10Amp].limit_min = 0.08*METER_ADC_MAX;
    multimeter.para[kMeterCh_V_1Amp].limit_max = 0.85*METER_ADC_MAX;
    multimeter.para[kMeterCh_V_1Amp].limit_min = 0.08*METER_ADC_MAX;
    multimeter.para[kMeterCh_mV_10Amp].limit_max = 0.85*METER_ADC_MAX;
    multimeter.para[kMeterCh_mV_10Amp].limit_min = 0.08*METER_ADC_MAX;
    multimeter.para[kMeterCh_mV_1Amp].limit_max = 0.85*METER_ADC_MAX;
    multimeter.para[kMeterCh_mV_1Amp].limit_min = 0.08*METER_ADC_MAX;
    multimeter.para[kMeterCh_A_1Amp].limit_max = 0.85*METER_ADC_MAX;
    multimeter.para[kMeterCh_A_1Amp].limit_min = 0.08*METER_ADC_MAX;
    multimeter.para[kMeterCh_D].limit_max = 0.85*METER_ADC_MAX;
    multimeter.para[kMeterCh_D].limit_min = 0.08*METER_ADC_MAX;
    multimeter.para[kMeterCh_R].limit_max = 0.92*METER_ADC_MAX;
    multimeter.para[kMeterCh_R].limit_min = 0.07*METER_ADC_MAX;
    multimeter.para[kMeterCh_R_K].limit_max = 0.92*METER_ADC_MAX;
    multimeter.para[kMeterCh_R_K].limit_min = 0.07*METER_ADC_MAX;
    multimeter.para[kMeterCh_R_M].limit_max = 1*METER_ADC_MAX;
    multimeter.para[kMeterCh_R_M].limit_min = 0.07*METER_ADC_MAX;
    //初始化校准系数
    for(i=0;i!=SECTION_FACTOR_NUM;i++) {
        multimeter.para[i].factor = &section_factor[i];
        multimeter.para[i].factor_type = kMeterFactorType_Section;
    }
    multimeter.para[kMeterCh_R].factor_type = kMeterFactorType_R;
    multimeter.para[kMeterCh_R_K].factor_type = kMeterFactorType_R;
    multimeter.para[kMeterCh_R_M].factor_type = kMeterFactorType_R;
    
    multimeter.channel = kBoardMetetCh_R;
    multimeter_select_channel(kBoardMetetCh_V); //默认开机电压档
}

__IO int32_t test_buff[256];
__IO uint8_t test_buff_cnt = 0;

void task_meter(void *para)
{
    multimeter_init();
    board.adc_dev.bus->int_enable(board.adc_dev.bus_handle, 1);
    while(1)
    {
        if(xSemaphoreTake(xSemaphore_adc_int, 2000) == pdTRUE) { //检测到CS1237_BUFF_SIZE次采样值
            multimeter.adc_value = read_adc_average();
            test_buff[test_buff_cnt++] = multimeter.adc_value; ////测试，后续删除
            meter_cal(&multimeter);
            multimeter.valid = 1;
        }
        else { //芯片引脚电平变化检测不到
            multimeter.valid = 0;
        }
        //vTaskDelay(50);
    }
}

